package com.zzyl.nursing.service.impl;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zzyl.common.exception.ServiceException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.nursing.domain.CheckInConfig;
import com.zzyl.nursing.domain.Contract;
import com.zzyl.nursing.domain.Elder;
import com.zzyl.nursing.dto.CheckInApplyDto;
import com.zzyl.nursing.dto.CheckInElderDto;
import com.zzyl.nursing.mapper.*;
import com.zzyl.utils.CodeGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.domain.CheckIn;
import com.zzyl.nursing.service.ICheckInService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;

/**
 * 入住信息Service业务层处理
 * 
 * @author laoYe
 * @date 2025-10-21
 */
@Service
public class CheckInServiceImpl extends ServiceImpl<CheckInMapper, CheckIn> implements ICheckInService {
    @Autowired
    private CheckInMapper checkInMapper;

    /**
     * 查询入住信息
     * 
     * @param id 入住信息主键
     * @return 入住信息
     */
    @Override
    public CheckIn selectCheckInById(Long id) {
        return getById(id);
    }

    /**
     * 查询入住信息列表
     * 
     * @param checkIn 入住信息
     * @return 入住信息
     */
    @Override
    public List<CheckIn> selectCheckInList(CheckIn checkIn) {
        return checkInMapper.selectCheckInList(checkIn);
    }

    /**
     * 新增入住信息
     * 
     * @param checkIn 入住信息
     * @return 结果
     */
    @Override
    public int insertCheckIn(CheckIn checkIn) {
        return save(checkIn) ? 1 : 0;
    }

    /**
     * 修改入住信息
     * 
     * @param checkIn 入住信息
     * @return 结果
     */
    @Override
    public int updateCheckIn(CheckIn checkIn) {
        return updateById(checkIn) ? 1 : 0;
    }

    /**
     * 批量删除入住信息
     * 
     * @param ids 需要删除的入住信息主键
     * @return 结果
     */
    @Override
    public int deleteCheckInByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除入住信息信息
     * 
     * @param id 入住信息主键
     * @return 结果
     */
    @Override
    public int deleteCheckInById(Long id) {
        return removeById(id) ? 1 : 0;
    }

    @Autowired
    private ElderMapper elderMapper;

    @Autowired
    private BedMapper bedMapper;

    /**
     * 入住办理
     *
     * @param checkInApplyDto
     */
    @Transactional
    @Override
    public void apply(CheckInApplyDto checkInApplyDto) {
        //TODO 入住办理
        // 1. 保存老人信息checkInElderDto
        //  老是否存在，如果存在则更新
        //    通过身份证号码查询
        Elder elder = elderMapper.selectOne(new LambdaQueryWrapper<Elder>().eq(Elder::getIdCardNo, checkInApplyDto.getCheckInElderDto().getIdCardNo()));
        // 判断才人是否已入住了
        if(null != elder){
            if(elder.getStatus()>=2 && elder.getStatus()<=4){
                throw new ServiceException("该老人已入住");
            }
        }
        // 老人没入住
        //    checkinconfig中的床位id去查询床位的编号
        //    更新床位的状态, 更新结果，通过影响的记录，如果影响记录数>0则表示更新成功。乐观锁案例,利用数据库的行锁
        int rows = bedMapper.updateBedStatus(checkInApplyDto.getCheckInConfigDto().getBedId());
        if(rows == 0){
            //床位已经有人了
            throw new ServiceException("该床位已有人，请选择其它床");
        }
        //  不存在则新增老人
        Elder newElder = saveOrUpdateElder(checkInApplyDto, elder);
        // 2. 保存入住信息
        CheckIn checkIn = addCheckIn(checkInApplyDto, newElder);
        // 3. 添加入住合同信息
        addContract(checkInApplyDto,checkIn);
        // 4. 添加入住配置信息
        addCheckConfig(checkInApplyDto, checkIn);
    }

    @Autowired
    private CheckInConfigMapper checkInConfigMapper;

    /**
     * 添加入住配置信息
     * @param checkInApplyDto
     * @param checkIn
     */
    private void addCheckConfig(CheckInApplyDto checkInApplyDto, CheckIn checkIn) {
        CheckInConfig config = BeanUtil.toBean(checkInApplyDto.getCheckInConfigDto(), CheckInConfig.class);
        config.setCheckInId(checkIn.getId());
        config.setCreateTime(new Date());
        config.setUpdateTime(checkIn.getCreateTime());

        checkInConfigMapper.insert(config);
    }


    @Autowired
    private ContractMapper contractMapper;

    /**
     * 添加合同信息
     * @param checkInApplyDto
     * @param checkIn
     */
    private void addContract(CheckInApplyDto checkInApplyDto, CheckIn checkIn) {
        Contract contract = BeanUtil.toBean(checkInApplyDto.getCheckInContractDto(), Contract.class);
        contract.setCheckInId(checkIn.getId());
        contract.setElderId(checkIn.getElderId());
        String contractNumber = CodeGenerator.generateContractNumber();
        contract.setContractNumber(contractNumber);

        contract.setElderName(checkIn.getElderName());
        contract.setStartDate(checkIn.getStartDate());
        contract.setEndDate(checkIn.getEndDate());

        contract.setStatus(0);//未生效

        contract.setCreateTime(new Date());
        contract.setUpdateTime(contract.getCreateTime());

        contractMapper.insert(contract);
    }

    /**
     * 添加入住信息
     * @param checkInApplyDto
     * @param newElder
     */
    private CheckIn addCheckIn(CheckInApplyDto checkInApplyDto, Elder newElder) {
        CheckIn checkIn = new CheckIn();
        // 老人信息
        checkIn.setElderId(newElder.getId());
        checkIn.setElderName(newElder.getName());
        checkIn.setIdCardNo(newElder.getIdCardNo());

        checkIn.setStartDate(checkInApplyDto.getCheckInConfigDto().getStartDate());
        checkIn.setEndDate(checkInApplyDto.getCheckInConfigDto().getEndDate());
        checkIn.setNursingLevelName(checkInApplyDto.getCheckInConfigDto().getNursingLevelName());

        //床位
        checkIn.setBedNumber(newElder.getBedNumber());
        checkIn.setStatus(0);//未入住

        checkIn.setCreateTime(new Date());
        checkIn.setUpdateTime(checkIn.getCreateTime());

        //remark，老人的家属联系人,转成json字符串
        String jsonStr = JSONUtil.toJsonStr(checkInApplyDto.getElderFamilyDtoList());
        checkIn.setRemark(jsonStr);

        save(checkIn);//要使用MP的方法
        return checkIn;
    }

    /**
     * 保存老人信息操作
     * @param checkInApplyDto
     * @param elder
     */
    private Elder saveOrUpdateElder(CheckInApplyDto checkInApplyDto, Elder elder) {

        CheckInElderDto checkInElderDto = checkInApplyDto.getCheckInElderDto();
        // 对象数据拷贝
        Elder newElder = BeanUtil.toBean(checkInElderDto, Elder.class);
        // 要设置新的床位编号
        //       要获取床位编号bed_number, 通过id查询，
        //  床位的id
        Long bedId = checkInApplyDto.getCheckInConfigDto().getBedId();
        newElder.setBedNumber(bedMapper.selectBedById(bedId).getBedNumber());
        newElder.setBedId(bedId);//床位的id
        // 状态
        newElder.setStatus(1);//启用
        //判断老人是否存在
        if(elder != null){
            //更新
            //更新时间
            newElder.setUpdateTime(new Date());
            newElder.setId(elder.getId());
            elderMapper.updateById(newElder);
        }else{
            //新增
            newElder.setCreateTime(new Date());
            elderMapper.insert(newElder);//要使用MP的方法，自动填充id
        }
        return newElder;
    }

}
